package uk.co.kevinlockwood.kol.droid.activities;

import java.util.Date;

import uk.co.kevinlockwood.kol.JavaHelpers;
import uk.co.kevinlockwood.kol.KoLHelpers;
import uk.co.kevinlockwood.kol.droid.DroidHelpers;
import uk.co.kevinlockwood.kol.droid.G;
import uk.co.kevinlockwood.kol.droid.R;
import uk.co.kevinlockwood.kol.pages.CannotGetOnlineException;
import uk.co.kevinlockwood.kol.pages.KoLDroidVersionPage;
import uk.co.kevinlockwood.kol.pages.KoLPageBuilder;
import uk.co.kevinlockwood.kol.pages.LoginPage.LoginResult;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

public class Login extends Activity implements OnClickListener, Handler.Callback {

	// web links for this activity
	private static final Uri CHANGELOG_URL = Uri.parse("http://kevinlockwood.co.uk/kol/koldroid/changelog.php");
	private static final Uri NEW_CHARACTER_URL = Uri.parse("http://www.kingdomofloathing.com/createplayer.php");

	private SharedPreferences settings;
	private ProgressDialog p;
	private KoLPageBuilder builder;

	/** Called when the activity is first created */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		DroidHelpers.trace("Login.onCreate()");
		try {
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			settings = getSharedPreferences(G.PREFS_NAME, MODE_PRIVATE);
			builder = new KoLPageBuilder(this, null);
			setContentView(R.layout.login);
		} catch (Exception e) {
			DroidHelpers.printStackTrace(e);
		}
	}

	@Override
	protected void onStart() {
		super.onStart();
		DroidHelpers.trace("Login.onStart()");
		DroidHelpers.setupActivity(this, settings);
		try {

			// bind to buttons - do we have to do this explicitly?
			findViewById(R.id.button_login).setOnClickListener(this);
			findViewById(R.id.button_newaccount).setOnClickListener(this);

			// load username and password if we have them
			String username = settings.getString(G.USER_NAME, G.BLANK);
			Boolean autologin = settings.getBoolean(G.AUTO_LOG_IN, Boolean.FALSE);
			((EditText)findViewById(R.id.input_username)).setText(username);
			((CheckBox)findViewById(R.id.checkbox_autosignin)).setChecked(autologin);

			// show current version - releases look like "x.y" (eg. 0.2, 1.0), betas look like "x.y.z" (eg. 0.1.4, 1.2.0)
			Resources res = getResources();
			String currentVersion = DroidHelpers.getVersion(this);
			DroidHelpers.log("current version: ",currentVersion);
			TextView tvCurrentVersion = (TextView)findViewById(R.id.currentVersionDisplay);
			tvCurrentVersion.setText(res.getString(R.string.currentVersion, currentVersion));
			Boolean isBeta = currentVersion.lastIndexOf(".") != currentVersion.indexOf("."); // we're beta if there's more than one '.' in the version

			// get latest version info
			KoLDroidVersionPage vp = builder.buildPage(new KoLDroidVersionPage(isBeta));
			String latestVersion = vp.getVersion();
			DroidHelpers.log("latest version: ",latestVersion);
			TextView tvNews = (TextView)findViewById(R.id.newsDisplay);
			tvNews.setText(vp.getNews());

			// is the service running already (ie. are we logging out now?)
			long now = new Date().getTime();
			long last = settings.getLong(G.LAST_UPDATE, -1);
			DroidHelpers.log("checking if we are logged in - now=[",now,"] last=[",last,"]");
			if (now < last+3000) { // were we updated within the last 3000 milliseconds?
				// we must be on the way out...
				DroidHelpers.log("on the way out - clear up");
				Editor e = settings.edit();
				e.putString(G.SESSION_ID, null);
				e.commit();
			} else if (!currentVersion.equals(latestVersion)) {
				Builder b = new Builder(this);
				b.setMessage(res.getString(R.string.updateAvailable, latestVersion));
				b.setPositiveButton(R.string.update, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						DroidHelpers.openWebUrl(Login.this, CHANGELOG_URL);
						dialog.dismiss();
					}
				});
				b.setNeutralButton(R.string.ignore, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						doAutoLogin();
						dialog.dismiss();
					}
				});
				AlertDialog a = b.create();
				a.setOwnerActivity(this);
				a.show();
			} else {
				doAutoLogin();
			}
		} catch (Exception e) {
			DroidHelpers.printStackTrace(e);
		}
	}

	@Override
	protected void onDestroy() {
		DroidHelpers.trace("Login.onDestroy()");
		super.onDestroy();
		try {
			DroidHelpers.log("Goodbye, Dave!");
		} catch (Exception e) {
			DroidHelpers.printStackTrace(e);
		}
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		DroidHelpers.trace("Login.onConfigurationChanged()");
		super.onConfigurationChanged(newConfig);
	}

	@Override
	public void onBackPressed() {
		DroidHelpers.trace("Login.onBackPressed()");
		super.onBackPressed();
	}

	@Override
	protected void onStop() {
		DroidHelpers.trace("Login.onStop()");
		super.onStop();
	}
	
	private void doAutoLogin() {
		Boolean autologin = settings.getBoolean(G.AUTO_LOG_IN, Boolean.FALSE);
		if (autologin) {
			DroidHelpers.log("set to auto login - logging in");
			String username = settings.getString(G.USER_NAME, G.BLANK);
			String passhash = settings.getString(G.PASS_WORD, G.BLANK);
			doLogin(username, passhash);
		} else {
			DroidHelpers.log("not set to auto login");
		}
	}

	private void clickLogin() {
		DroidHelpers.trace("login button pressed");
		String username = ((EditText)findViewById(R.id.input_username)).getText().toString();
		String password = ((EditText)findViewById(R.id.input_password)).getText().toString();
		Boolean autochk = ((CheckBox)findViewById(R.id.checkbox_autosignin)).isChecked();
		String passhash = JavaHelpers.md5sum(password);
		Editor e = settings.edit();
		e.putString(G.USER_NAME, username);
		if (autochk) {
			e.putString(G.PASS_WORD, passhash);
		} else {
			e.remove(G.PASS_WORD);
		}
		e.putBoolean(G.AUTO_LOG_IN, autochk);
		e.commit();
		doLogin(username, passhash);
	}

	private void doLogin(String user, String passhash) {
		p = ProgressDialog.show(this, G.BLANK, getResources().getString(R.string.loggingIn), true, false);
		new LoginThread(user, passhash, new Handler(this)).start();
	}

	private class LoginThread extends Thread {
		String user;
		String passhash;
		Handler h;
		public LoginThread(String user, String passhash, Handler h) {
			super();
			this.user = user;
			this.passhash = passhash;
			this.h = h;
		}
		public void run() {
			// try and login
			LoginResult result;
			try {
				result = KoLHelpers.getSessionId(builder, user, passhash);
			} catch (CannotGetOnlineException e) {
				result = LoginResult.NOT_ONLINE;
			}
			Message msg = Message.obtain();
			msg.obj = result;
			h.sendMessage(msg);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.button_login:
			clickLogin();
			break;
		case R.id.button_newaccount:
			DroidHelpers.trace("create a character button pressed");
			DroidHelpers.openWebUrl(this, NEW_CHARACTER_URL);
			break;
		}
	}

	@Override
	public boolean handleMessage(Message msg) {
		if (msg.obj instanceof LoginResult) {
			LoginResult result = (LoginResult)msg.obj;

			// deal with outcome of login
			int stringid = R.string.login;
			switch (result) {
			case SUCCESS:
				Editor e = settings.edit();
				e.putString(G.SESSION_ID, result.id);
				e.commit();
				Intent i = new Intent(this, Chat.class);
				startActivity(i);
				break;
			case ALREADY_LOGGED_IN:
				stringid = R.string.alreadyLoggedIn;
				break;
			case WRONG_PASSWORD:
				stringid = R.string.wrongPassword;
				break;
			case NOT_ONLINE:
				stringid = R.string.notConnected;
				break;
			case ROLL_OVER:
				stringid = R.string.rollover;
				break;
			case NOT_LOGGED_IN:
			case UNKNOWN:
			default:
				stringid = R.string.loginFailed;
				break;
			}

			// deal with message box
			p.dismiss();
			if (stringid != R.string.login) {
				Builder b = new Builder(this);
				b.setMessage(stringid);
				AlertDialog a = b.create();
				a.setOwnerActivity(this);
				a.show();
			}
			return true;
		}
		return false;
	}
}